home *** CD-ROM | disk | FTP | other *** search
/ Risc World 5 / Risc World 5.iso / SOFTWARE / Issue3 / Games / xrick / !xrick / src / c / e_rick < prev    next >
Text File  |  2004-06-24  |  11KB  |  567 lines

  1. /*
  2.  * xrick/src/e_rick.c
  3.  *
  4.  * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
  5.  *
  6.  * The use and distribution terms for this software are contained in the file
  7.  * named README, which can be found in the root of this distribution. By
  8.  * using this software in any fashion, you are agreeing to be bound by the
  9.  * terms of this license.
  10.  *
  11.  * You must not remove this notice, or any other, from this software.
  12.  */
  13.  
  14. #include "system.h"
  15. #include "config.h"
  16. #include "game.h"
  17. #include "ents.h"
  18. #include "e_rick.h"
  19.  
  20. #include "e_bullet.h"
  21. #include "e_bomb.h"
  22. #include "control.h"
  23. #include "maps.h"
  24. #include "util.h"
  25.  
  26. /*
  27.  * public vars
  28.  */
  29. S16 e_rick_stop_x = 0;
  30. S16 e_rick_stop_y = 0;
  31. U8 e_rick_state = 0;
  32.  
  33. /*
  34.  * local vars
  35.  */
  36. static U8 scrawl;
  37.  
  38. static U8 trigger = FALSE;
  39.  
  40. static S8 offsx;
  41. static U8 ylow;
  42. static S16 offsy;
  43.  
  44. static U8 seq;
  45.  
  46. static U8 save_crawl;
  47. static U16 save_x, save_y;
  48.  
  49.  
  50. /*
  51.  * Box test
  52.  *
  53.  * ASM 113E (based on)
  54.  *
  55.  * e: entity to test against (corresponds to SI in asm code -- here DI
  56.  *    is assumed to point to rick).
  57.  * ret: TRUE/intersect, FALSE/not.
  58.  */
  59. U8
  60. e_rick_boxtest(U8 e)
  61. {
  62.     /*
  63.      * rick: x+0x05 to x+0x11, y+[0x08 if rick's crawling] to y+0x14
  64.      * entity: x to x+w, y to y+h
  65.      */
  66.  
  67.     if (E_RICK_ENT.x + 0x11 < ent_ents[e].x ||
  68.         E_RICK_ENT.x + 0x05 > ent_ents[e].x + ent_ents[e].w ||
  69.         E_RICK_ENT.y + 0x14 < ent_ents[e].y ||
  70.         E_RICK_ENT.y + (E_RICK_STTST(E_RICK_STCRAWL) ? 0x08 : 0x00) > ent_ents[e].y + ent_ents[e].h - 1)
  71.         return FALSE;
  72.     else
  73.         return TRUE;
  74. }
  75.  
  76.  
  77.  
  78.  
  79. /*
  80.  * Go zombie
  81.  *
  82.  * ASM 1851
  83.  */
  84. void
  85. e_rick_gozombie(void)
  86. {
  87. #ifdef ENABLE_CHEATS
  88.     if (game_cheat2) return;
  89. #endif
  90.  
  91.     /* already zombie? */
  92.     if E_RICK_STTST(E_RICK_STZOMBIE) return;
  93.  
  94. #ifdef ENABLE_SOUND
  95.     syssnd_play(WAV_DIE, 1);
  96. #endif
  97.  
  98.     E_RICK_STSET(E_RICK_STZOMBIE);
  99.     offsy = -0x0400;
  100.     offsx = (E_RICK_ENT.x > 0x80 ? -3 : +3);
  101.     ylow = 0;
  102.     E_RICK_ENT.front = TRUE;
  103. }
  104.  
  105.  
  106. /*
  107.  * Action sub-function for e_rick when zombie
  108.  *
  109.  * ASM 17DC
  110.  */
  111. static void
  112. e_rick_z_action(void)
  113. {
  114.     U32 i;
  115.  
  116.     /* sprite */
  117.     E_RICK_ENT.sprite = (E_RICK_ENT.x & 0x04) ? 0x1A : 0x19;
  118.  
  119.     /* x */
  120.     E_RICK_ENT.x += offsx;
  121.  
  122.     /* y */
  123.     i = (E_RICK_ENT.y << 8) + offsy + ylow;
  124.     E_RICK_ENT.y = i >> 8;
  125.     offsy += 0x80;
  126.     ylow = i;
  127.  
  128.     /* dead when out of screen */
  129.     if (E_RICK_ENT.y < 0 || E_RICK_ENT.y > 0x0140)
  130.         E_RICK_STSET(E_RICK_STDEAD);
  131. }
  132.  
  133.  
  134. /*
  135.  * Action sub-function for e_rick.
  136.  *
  137.  * ASM 13BE
  138.  */
  139. void
  140. e_rick_action2(void)
  141. {
  142.     U8 env0, env1;
  143.     S16 x, y;
  144.     U32 i;
  145.  
  146.     E_RICK_STRST(E_RICK_STSTOP|E_RICK_STSHOOT);
  147.  
  148.     /* if zombie, run dedicated function and return */
  149.     if E_RICK_STTST(E_RICK_STZOMBIE) {
  150.         e_rick_z_action();
  151.         return;
  152.     }
  153.  
  154.     /* climbing? */
  155.     if E_RICK_STTST(E_RICK_STCLIMB)
  156.         goto climbing;
  157.  
  158.     /*
  159.     * NOT CLIMBING
  160.     */
  161.     E_RICK_STRST(E_RICK_STJUMP);
  162.     /* calc y */
  163.     i = (E_RICK_ENT.y << 8) + offsy + ylow;
  164.     y = i >> 8;
  165.     /* test environment */
  166.     u_envtest(E_RICK_ENT.x, y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
  167.     /* stand up, if possible */
  168.     if (E_RICK_STTST(E_RICK_STCRAWL) && !env0)
  169.         E_RICK_STRST(E_RICK_STCRAWL);
  170.     /* can move vertically? */
  171.     if (env1 & (offsy < 0 ?
  172.                     MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD :
  173.                     MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))
  174.         goto vert_not;
  175.  
  176.     /*
  177.     * VERTICAL MOVE
  178.     */
  179.     E_RICK_STSET(E_RICK_STJUMP);
  180.     /* killed? */
  181.     if (env1 & MAP_EFLG_LETHAL) {
  182.         e_rick_gozombie();
  183.         return;
  184.     }
  185.     /* save */
  186.     E_RICK_ENT.y = y;
  187.     ylow = i;
  188.     /* climb? */
  189.     if ((env1 & MAP_EFLG_CLIMB) &&
  190.             (control_status & (CONTROL_UP|CONTROL_DOWN))) {
  191.         offsy = 0x0100;
  192.         E_RICK_STSET(E_RICK_STCLIMB);
  193.         return;
  194.     }
  195.     /* fall */
  196.     offsy += 0x0080;
  197.     if (offsy > 0x0800) {
  198.         offsy = 0x0800;
  199.         ylow = 0;
  200.     }
  201.  
  202.     /*
  203.     * HORIZONTAL MOVE
  204.     */
  205.     horiz:
  206.     /* should move? */
  207.     if (!(control_status & (CONTROL_LEFT|CONTROL_RIGHT))) {
  208.         seq = 2; /* no: reset seq and return */
  209.         return;
  210.     }
  211.     if (control_status & CONTROL_LEFT) {  /* move left */
  212.         x = E_RICK_ENT.x - 2;
  213.         game_dir = LEFT;
  214.         if (x < 0) {  /* prev submap */
  215.             game_chsm = TRUE;
  216.             E_RICK_ENT.x = 0xe2;
  217.             return;
  218.         }
  219.     } else {  /* move right */
  220.         x = E_RICK_ENT.x + 2;
  221.         game_dir = RIGHT;
  222.         if (x >= 0xe8) {  /* next submap */
  223.             game_chsm = TRUE;
  224.             E_RICK_ENT.x = 0x04;
  225.             return;
  226.         }
  227.     }
  228.  
  229.     /* still within this map: test environment */
  230.     u_envtest(x, E_RICK_ENT.y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
  231.  
  232.     /* save x-position if it is possible to move */
  233.     if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) {
  234.         E_RICK_ENT.x = x;
  235.         if (env1 & MAP_EFLG_LETHAL) e_rick_gozombie();
  236.     }
  237.  
  238.     /* end */
  239.     return;
  240.  
  241.   /*
  242.    * NO VERTICAL MOVE
  243.    */
  244.  vert_not:
  245.   if (offsy < 0) {
  246.     /* not climbing + trying to go _up_ not possible -> hit the roof */
  247.     E_RICK_STSET(E_RICK_STJUMP);  /* fall back to the ground */
  248.     E_RICK_ENT.y &= 0xF8;
  249.     offsy = 0;
  250.     ylow = 0;
  251.     goto horiz;
  252.   }
  253.   /* else: not climbing + trying to go _down_ not possible -> standing */
  254.   /* align to ground */
  255.   E_RICK_ENT.y &= 0xF8;
  256.   E_RICK_ENT.y |= 0x03;
  257.   ylow = 0;
  258.  
  259.   /* standing on a super pad? */
  260.   if ((env1 & MAP_EFLG_SPAD) && offsy >= 0X0200) {
  261.     offsy = (control_status & CONTROL_UP) ? 0xf800 : 0x00fe - offsy;
  262. #ifdef ENABLE_SOUND
  263.     syssnd_play(WAV_PAD, 1);
  264. #endif
  265.     goto horiz;
  266.   }
  267.  
  268.   offsy = 0x0100;  /* reset*/
  269.  
  270.   /* standing. firing ? */
  271.   if (scrawl || !(control_status & CONTROL_FIRE))
  272.     goto firing_not;
  273.  
  274.   /*
  275.    * FIRING
  276.    */
  277.     if (control_status & (CONTROL_LEFT|CONTROL_RIGHT)) {  /* stop */
  278.         if (control_status & CONTROL_RIGHT)
  279.         {
  280.             game_dir = RIGHT;
  281.             e_rick_stop_x = E_RICK_ENT.x + 0x17;
  282.         } else {
  283.             game_dir = LEFT;
  284.             e_rick_stop_x = E_RICK_ENT.x;
  285.         }
  286.         e_rick_stop_y = E_RICK_ENT.y + 0x000E;
  287.         E_RICK_STSET(E_RICK_STSTOP);
  288.         return;
  289.     }
  290.  
  291.   if (control_status == (CONTROL_FIRE|CONTROL_UP)) {  /* bullet */
  292.     E_RICK_STSET(E_RICK_STSHOOT);
  293.     /* not an automatic gun: shoot once only */
  294.     if (trigger)
  295.       return;
  296.     else
  297.       trigger = TRUE;
  298.     /* already a bullet in the air ... that's enough */
  299.     if (E_BULLET_ENT.n)
  300.       return;
  301.     /* else use a bullet, if any available */
  302.     if (!game_bullets)
  303.       return;
  304. #ifdef ENABLE_CHEATS
  305.     if (!game_cheat1)
  306.       game_bullets--;
  307. #endif
  308.     /* initialize bullet */
  309.     e_bullet_init(E_RICK_ENT.x, E_RICK_ENT.y);
  310.     return;
  311.   }
  312.  
  313.   trigger = FALSE; /* not shooting means trigger is released */
  314.   seq = 0; /* reset */
  315.  
  316.   if (control_status == (CONTROL_FIRE|CONTROL_DOWN)) {  /* bomb */
  317.     /* already a bomb ticking ... that's enough */
  318.     if (E_BOMB_ENT.n)
  319.       return;
  320.     /* else use a bomb, if any available */
  321.     if (!game_bombs)
  322.       return;
  323. #ifdef ENABLE_CHEATS
  324.     if (!game_cheat1)
  325.       game_bombs--;
  326. #endif
  327.     /* initialize bomb */
  328.     e_bomb_init(E_RICK_ENT.x, E_RICK_ENT.y);
  329.     return;
  330.   }
  331.  
  332.   return;
  333.  
  334.   /*
  335.    * NOT FIRING
  336.    */
  337.  firing_not:
  338.   if (control_status & CONTROL_UP) {  /* jump or climb */
  339.     if (env1 & MAP_EFLG_CLIMB) {  /* climb */
  340.       E_RICK_STSET(E_RICK_STCLIMB);
  341.       return;
  342.     }
  343.     offsy = -0x0580;  /* jump */
  344.     ylow = 0;
  345. #ifdef ENABLE_SOUND
  346.     syssnd_play(WAV_JUMP, 1);
  347. #endif
  348.     goto horiz;
  349.   }
  350.   if (control_status & CONTROL_DOWN) {  /* crawl or climb */
  351.     if ((env1 & MAP_EFLG_VERT) &&  /* can go down */
  352.     !(control_status & (CONTROL_LEFT|CONTROL_RIGHT)) &&  /* + not moving horizontaly */
  353.     (E_RICK_ENT.x & 0x1f) < 0x0a) {  /* + aligned -> climb */
  354.       E_RICK_ENT.x &= 0xf0;
  355.       E_RICK_ENT.x |= 0x04;
  356.       E_RICK_STSET(E_RICK_STCLIMB);
  357.     }
  358.     else {  /* crawl */
  359.       E_RICK_STSET(E_RICK_STCRAWL);
  360.       goto horiz;
  361.     }
  362.  
  363.   }
  364.   goto horiz;
  365.  
  366.     /*
  367.     * CLIMBING
  368.     */
  369.     climbing:
  370.         /* should move? */
  371.         if (!(control_status & (CONTROL_UP|CONTROL_DOWN|CONTROL_LEFT|CONTROL_RIGHT))) {
  372.             seq = 0; /* no: reset seq and return */
  373.             return;
  374.         }
  375.  
  376.         if (control_status & (CONTROL_UP|CONTROL_DOWN)) {
  377.             /* up-down: calc new y and test environment */
  378.             y = E_RICK_ENT.y + ((control_status & CONTROL_UP) ? -0x02 : 0x02);
  379.             u_envtest(E_RICK_ENT.x, y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
  380.             if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP) &&
  381.                     !(control_status & CONTROL_UP)) {
  382.                 /* FIXME what? */
  383.                 E_RICK_STRST(E_RICK_STCLIMB);
  384.                 return;
  385.             }
  386.             if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) ||
  387.                     (env1 & MAP_EFLG_WAYUP)) {
  388.                 /* ok to move, save */
  389.                 E_RICK_ENT.y = y;
  390.                 if (env1 & MAP_EFLG_LETHAL) {
  391.                     e_rick_gozombie();
  392.                     return;
  393.                 }
  394.                 if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB))) {
  395.                     /* reached end of climb zone */
  396.                     offsy = (control_status & CONTROL_UP) ? -0x0300 : 0x0100;
  397. #ifdef ENABLE_SOUND
  398.                     if (control_status & CONTROL_UP)
  399.                         syssnd_play(WAV_JUMP, 1);
  400. #endif
  401.                     E_RICK_STRST(E_RICK_STCLIMB);
  402.                     return;
  403.                 }
  404.             }
  405.         }
  406.   if (control_status & (CONTROL_LEFT|CONTROL_RIGHT)) {
  407.     /* left-right: calc new x and test environment */
  408.     if (control_status & CONTROL_LEFT) {
  409.       x = E_RICK_ENT.x - 0x02;
  410.       if (x < 0) {  /* (i.e. negative) prev submap */
  411.     game_chsm = TRUE;
  412.     /*6dbd = 0x00;*/
  413.     E_RICK_ENT.x = 0xe2;
  414.     return;
  415.       }
  416.     }
  417.     else {
  418.       x = E_RICK_ENT.x + 0x02;
  419.       if (x >= 0xe8) {  /* next submap */
  420.     game_chsm = TRUE;
  421.     /*6dbd = 0x01;*/
  422.     E_RICK_ENT.x = 0x04;
  423.     return;
  424.       }
  425.     }
  426.     u_envtest(x, E_RICK_ENT.y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1);
  427.     if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD)) return;
  428.     E_RICK_ENT.x = x;
  429.     if (env1 & MAP_EFLG_LETHAL) {
  430.       e_rick_gozombie();
  431.       return;
  432.     }
  433.  
  434.     if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) return;
  435.     E_RICK_STRST(E_RICK_STCLIMB);
  436.     if (control_status & CONTROL_UP)
  437.       offsy = -0x0300;
  438.   }
  439. }
  440.  
  441.  
  442. /*
  443.  * Action function for e_rick
  444.  *
  445.  * ASM 12CA
  446.  */
  447. void e_rick_action(UNUSED(U8 e))
  448. {
  449.     static U8 stopped = FALSE; /* is this the most elegant way? */
  450.  
  451.     e_rick_action2();
  452.  
  453.     scrawl = E_RICK_STTST(E_RICK_STCRAWL);
  454.  
  455.     if E_RICK_STTST(E_RICK_STZOMBIE)
  456.         return;
  457.  
  458.     /*
  459.      * set sprite
  460.      */
  461.  
  462.     if E_RICK_STTST(E_RICK_STSTOP) {
  463.         E_RICK_ENT.sprite = (game_dir ? 0x17 : 0x0B);
  464. #ifdef ENABLE_SOUND
  465.         if (!stopped)
  466.         {
  467.             syssnd_play(WAV_STICK, 1);
  468.             stopped = TRUE;
  469.         }
  470. #endif
  471.         return;
  472.     }
  473.  
  474.     stopped = FALSE;
  475.  
  476.     if E_RICK_STTST(E_RICK_STSHOOT) {
  477.         E_RICK_ENT.sprite = (game_dir ? 0x16 : 0x0A);
  478.         return;
  479.     }
  480.  
  481.     if E_RICK_STTST(E_RICK_STCLIMB) {
  482.         E_RICK_ENT.sprite = (((E_RICK_ENT.x ^ E_RICK_ENT.y) & 0x04) ? 0x18 : 0x0c);
  483. #ifdef ENABLE_SOUND
  484.         seq = (seq + 1) & 0x03;
  485.         if (seq == 0) syssnd_play(WAV_WALK, 1);
  486. #endif
  487.         return;
  488.     }
  489.  
  490.     if E_RICK_STTST(E_RICK_STCRAWL)
  491.     {
  492.         E_RICK_ENT.sprite = (game_dir ? 0x13 : 0x07);
  493.         if (E_RICK_ENT.x & 0x04) E_RICK_ENT.sprite++;
  494. #ifdef ENABLE_SOUND
  495.         seq = (seq + 1) & 0x03;
  496.         if (seq == 0) syssnd_play(WAV_CRAWL, 1);
  497. #endif
  498.         return;
  499.     }
  500.  
  501.     if E_RICK_STTST(E_RICK_STJUMP)
  502.     {
  503.         E_RICK_ENT.sprite = (game_dir ? 0x15 : 0x06);
  504.         return;
  505.     }
  506.  
  507.     seq++;
  508.  
  509.     if (seq >= 0x14)
  510.     {
  511. #ifdef ENABLE_SOUND
  512.         syssnd_play(WAV_WALK, 1);
  513. #endif
  514.         seq = 0x04;
  515.     }
  516. #ifdef ENABLE_SOUND
  517.   else
  518.   if (seq == 0x0C)
  519.     syssnd_play(WAV_WALK, 1);
  520. #endif
  521.  
  522.   E_RICK_ENT.sprite = (seq >> 2) + 1 + (game_dir ? 0x0c : 0x00);
  523. }
  524.  
  525.  
  526. /*
  527.  * Save status
  528.  *
  529.  * ASM part of 0x0BBB
  530.  */
  531. void e_rick_save(void)
  532. {
  533.     save_x = E_RICK_ENT.x;
  534.     save_y = E_RICK_ENT.y;
  535.     save_crawl = E_RICK_STTST(E_RICK_STCRAWL);
  536.     /* FIXME
  537.      * save_C0 = E_RICK_ENT.b0C;
  538.      * plus some 6DBC stuff?
  539.      */
  540. }
  541.  
  542.  
  543. /*
  544.  * Restore status
  545.  *
  546.  * ASM part of 0x0BDC
  547.  */
  548. void e_rick_restore(void)
  549. {
  550.     E_RICK_ENT.x = save_x;
  551.     E_RICK_ENT.y = save_y;
  552.     E_RICK_ENT.front = FALSE;
  553.     if (save_crawl)
  554.         E_RICK_STSET(E_RICK_STCRAWL);
  555.     else
  556.         E_RICK_STRST(E_RICK_STCRAWL);
  557.     /* FIXME
  558.      * E_RICK_ENT.b0C = save_C0;
  559.      * plus some 6DBC stuff?
  560.      */
  561. }
  562.  
  563.  
  564.  
  565.  
  566. /* eof */
  567.